#include <stdio.h>
#include <sys/time.h>
#include "lvgl.h"
#include "lv_drivers/display/fbdev.h"
#include "mouse_cursor_icon.h"
#include "tslib_drv.h"
#include "lvgl_drv.h"
#include "lvgl/src/misc/lv_log_file.h"
#include "lv_app_conf.h"

#define DISP_BUF_SIZE (128 * 1024)

static lv_indev_t *mouse_indev;
static lv_disp_draw_buf_t disp_buf;
static lv_disp_drv_t disp_drv;
static lv_indev_drv_t indev_drv;
static lv_color_t buf[DISP_BUF_SIZE];

// 获取系统时钟函数实现
uint32_t custom_tick_get(void) {
    static uint64_t start_ms = 0;
    if(start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    return (uint32_t)(now_ms - start_ms);
}

// LVGL驱动初始化函数实现
void lvgl_driver_init(void) {
    // 初始化 LVGL
    lv_init();
    printf("lv init finish\n");
    fflush(stdout);

    // 初始化日志文件
    lv_log_file_init();
    printf("log file init finish\n");
    fflush(stdout);

    // 初始化帧缓冲设备
    fbdev_init();
    printf("fbdev init finish\n");
    fflush(stdout);

    // 初始化触摸输入
    tslib_init();
    printf("tslib init finish\n");
    fflush(stdout);

    // 创建显示缓冲区
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);

    // 初始化并注册显示驱动
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = fbdev_flush;
    disp_drv.hor_res = 480;
    disp_drv.ver_res = 272;
    lv_disp_drv_register(&disp_drv);

    // 初始化并注册触摸输入驱动
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = tslib_read;
    mouse_indev = lv_indev_drv_register(&indev_drv);

    // 设置鼠标光标
    LV_IMG_DECLARE(mouse_cursor_icon);
    lv_obj_t * cursor_obj = lv_img_create(lv_scr_act());
    lv_img_set_src(cursor_obj, &mouse_cursor_icon);
    lv_indev_set_cursor(mouse_indev, cursor_obj);

    // 移除根容器的默认边框和内边距
    lv_obj_t *scr = lv_scr_act();
    lv_obj_set_style_pad_all(scr, 0, LV_PART_MAIN);
    lv_obj_set_style_border_width(scr, 0, LV_PART_MAIN);

    printf("lvgl init finish\n");
    fflush(stdout);
}